﻿using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;

namespace Haimen.Excel;

internal static class SSTableMaker {

  public static LgeSharedStrTable Make(WorkbookPart bookPart) {
    SharedStringTablePart? sstPart = bookPart.SharedStringTablePart;
    Debug.Assert(sstPart != null);

    OpenXmlReader reader = OpenXmlReader.Create(sstPart);
    List<string> table = [];
    Reading reading = new();
    Task.Run(() => ReadSst(reader, table, reading));

    //while (reader.Read()) {
    //  if (reader.IsEndElement) {
    //    continue;
    //  }
    //
    //  Console.WriteLine(reader.ElementType);
    //  Console.WriteLine(string.Join(',', reader.Attributes.Select(a => $"{a.LocalName}={a.Value}")));
    //
    //  break;
    //}

    return new TableImpl(table, reading);
  }

  static int GetTableSize(OpenXmlReader reader) {
    while (reader.Read()) {
      if (reader.IsEndElement) {
        continue;
      }

      foreach (OpenXmlAttribute attr in reader.Attributes) {
        if ("uniqueCount".Equals(attr.LocalName)) {
          return int.Parse(attr.Value!);
        }
      }
    }

    return -1;
  }

  static void ReadSst(OpenXmlReader reader, List<string> table, Reading reading) {
    int index = 0;

    while (reader.Read()) {
      if (reader.IsEndElement) {
        continue;
      }

      //Console.WriteLine(reader.ElementType);
      if (reader.ElementType != typeof(Text)) {
        continue;
      }

      table.Add(reader.GetText());
      reading.Index = index++;
    }

    reader.Dispose();
  }

  class Reading {
    public int Index = -1;
  }

  record TableImpl(IList<string> Table, Reading Read) : LgeSharedStrTable {
    public async Task<string> Get(int index) {
      while (Read.Index < index) {
        await Task.Yield();
      }
      return Table[index];
    }

    public async Task<string> GetVal(LargeExcelCell cell) {
      if ("s".Equals(cell.Type)) {
        int index = int.Parse(cell.Value);
        return await Get(index);
      }
      return cell.Value;
    }
  }
}
